// components/chart-component/chart-component.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    title: {
      type: String,
      value: '血压趋势图'
    },
    // 外部传入的数据，格式: [{date: '2023-10-01', systolic: 120, diastolic: 80}, ...]
    chartData: {
      type: Array,
      value: [],
      observer: function(newVal) {
        this.setData({
          originalData: newVal,
          noData: newVal.length === 0
        }, () => {
          if (newVal.length > 0) {
            this.processChartData();
          }
        });
      }
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    timeRange: 'week', // week, month, year
    processedData: [],
    originalData: [],
    showTooltip: false,
    tooltipData: {},
    noData: true,
    canvasWidth: 0,
    canvasHeight: 0
  },

  /**
   * 组件生命周期函数，在组件实例进入页面节点树时执行
   */
  attached() {
    // 初始化图表
    this.initChart();
    
    // 监听窗口尺寸变化，重新绘制图表
    wx.onWindowResize(this.handleWindowResize);
  },

  /**
   * 组件生命周期函数，在组件实例被从页面节点树移除时执行
   */
  detached() {
    wx.offWindowResize(this.handleWindowResize);
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 初始化图表
    initChart() {
      // 获取canvas尺寸
      const query = wx.createSelectorQuery().in(this);
      query.select('.chart-canvas').boundingClientRect(res => {
        if (res) {
          this.setData({
            canvasWidth: res.width,
            canvasHeight: res.height
          }, () => {
            // 处理并绘制图表
            if (this.data.originalData.length > 0) {
              this.processChartData();
            }
          });
        }
      }).exec();
    },

    // 处理图表数据
    processChartData() {
      const { timeRange, originalData } = this.data;
      let processedData = [];
      
      // 根据时间范围筛选和处理数据
      switch (timeRange) {
        case 'week':
          processedData = this.processWeekData(originalData);
          break;
        case 'month':
          processedData = this.processMonthData(originalData);
          break;
        case 'year':
          processedData = this.processYearData(originalData);
          break;
      }
      
      this.setData({
        processedData: processedData
      }, () => {
        this.drawChart();
      });
    },

    // 处理周数据
    processWeekData(data) {
      // 获取最近7天的数据
      const sevenDaysAgo = new Date();
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 6);
      
      return data
        .filter(item => new Date(item.recordTime) >= sevenDaysAgo)
        .sort((a, b) => new Date(a.recordTime) - new Date(b.recordTime))
        .map(item => ({
          date: this.formatDate(new Date(item.recordTime), 'MM-DD'),
          systolic: item.systolic,
          diastolic: item.diastolic
        }));
    },

    // 处理月数据
    processMonthData(data) {
      // 获取最近30天的数据，按周聚合
      const thirtyDaysAgo = new Date();
      thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 29);
      
      const filteredData = data
        .filter(item => new Date(item.recordTime) >= thirtyDaysAgo)
        .sort((a, b) => new Date(a.recordTime) - new Date(b.recordTime));
      
      // 按周聚合数据
      const weeklyData = {};
      filteredData.forEach(item => {
        const date = new Date(item.recordTime);
        const weekKey = `第${Math.ceil(date.getDate() / 7)}周`;
        
        if (!weeklyData[weekKey]) {
          weeklyData[weekKey] = {
            date: weekKey,
            systolic: [],
            diastolic: []
          };
        }
        
        weeklyData[weekKey].systolic.push(item.systolic);
        weeklyData[weekKey].diastolic.push(item.diastolic);
      });
      
      // 计算每周平均值
      return Object.values(weeklyData).map(week => ({
        date: week.date,
        systolic: Math.round(this.average(week.systolic)),
        diastolic: Math.round(this.average(week.diastolic))
      }));
    },

    // 处理年数据
    processYearData(data) {
      // 获取最近12个月的数据，按月聚合
      const twelveMonthsAgo = new Date();
      twelveMonthsAgo.setMonth(twelveMonthsAgo.getMonth() - 11);
      
      const filteredData = data
        .filter(item => new Date(item.recordTime) >= twelveMonthsAgo)
        .sort((a, b) => new Date(a.recordTime) - new Date(b.recordTime));
      
      // 按月聚合数据
      const monthlyData = {};
      filteredData.forEach(item => {
        const date = new Date(item.recordTime);
        const monthKey = this.formatDate(date, 'MM月');
        
        if (!monthlyData[monthKey]) {
          monthlyData[monthKey] = {
            date: monthKey,
            systolic: [],
            diastolic: []
          };
        }
        
        monthlyData[monthKey].systolic.push(item.systolic);
        monthlyData[monthKey].diastolic.push(item.diastolic);
      });
      
      // 计算每月平均值
      return Object.values(monthlyData).map(month => ({
        date: month.date,
        systolic: Math.round(this.average(month.systolic)),
        diastolic: Math.round(this.average(month.diastolic))
      }));
    },

    // 绘制图表
    drawChart() {
      const { processedData, canvasWidth, canvasHeight } = this.data;
      
      if (!canvasWidth || !canvasHeight || processedData.length === 0) {
        this.setData({ noData: true });
        return;
      }
      
      this.setData({ noData: false });
      
      // 获取绘图上下文
      const ctx = wx.createCanvasContext('bloodPressureChart', this);
      
      // 图表边距
      const padding = { top: 30, right: 30, bottom: 40, left: 50 };
      const chartWidth = canvasWidth - padding.left - padding.right;
      const chartHeight = canvasHeight - padding.top - padding.bottom;
      
      // 清除画布
      ctx.clearRect(0, 0, canvasWidth, canvasHeight);
      
      // 绘制背景网格和坐标轴
      this.drawGrid(ctx, chartWidth, chartHeight, padding);
      
      // 绘制参考线（正常血压范围）
      this.drawReferenceLines(ctx, chartWidth, chartHeight, padding);
      
      // 绘制数据曲线
      if (processedData.length > 0) {
        this.drawDataLines(ctx, processedData, chartWidth, chartHeight, padding);
        
        // 绘制数据点
        this.drawDataPoints(ctx, processedData, chartWidth, chartHeight, padding);
      }
      
      // 绘制坐标轴标签
      this.drawAxisLabels(ctx, processedData, chartWidth, chartHeight, padding);
      
      // 绘制完成
      ctx.draw();
    },

    // 绘制网格和坐标轴
    drawGrid(ctx, width, height, padding) {
      ctx.setStrokeStyle('#e5e5e5');
      ctx.setLineWidth(1);
      
      // 绘制横向网格线（5条）
      for (let i = 0; i <= 5; i++) {
        const y = padding.top + (height / 5) * i;
        
        // 绘制横线
        ctx.beginPath();
        ctx.moveTo(padding.left, y);
        ctx.lineTo(padding.left + width, y);
        ctx.stroke();
        
        // 绘制纵轴刻度
        ctx.setFontSize(12);
        ctx.setFillStyle('#999999');
        ctx.setTextAlign('right');
        ctx.fillText(180 - (30 * i), padding.left - 10, y + 4);
      }
      
      // 绘制纵轴
      ctx.beginPath();
      ctx.setStrokeStyle('#cccccc');
      ctx.setLineWidth(1);
      ctx.moveTo(padding.left, padding.top);
      ctx.lineTo(padding.left, padding.top + height);
      ctx.stroke();
      
      // 绘制横轴
      ctx.beginPath();
      ctx.setStrokeStyle('#cccccc');
      ctx.setLineWidth(1);
      ctx.moveTo(padding.left, padding.top + height);
      ctx.lineTo(padding.left + width, padding.top + height);
      ctx.stroke();
    },

    // 绘制参考线（正常血压范围）
    drawReferenceLines(ctx, width, height, padding) {
      // 正常血压范围：收缩压 <= 130，舒张压 <= 85
      // 高血压警戒线：收缩压 140，舒张压 90
      
      ctx.setLineWidth(1);
      ctx.setDash([5, 5]);
      
      // 收缩压警戒线（140）
      const systolicWarningY = this.getValueY(140, padding.top, height);
      ctx.beginPath();
      ctx.setStrokeStyle('#ff9900');
      ctx.moveTo(padding.left, systolicWarningY);
      ctx.lineTo(padding.left + width, systolicWarningY);
      ctx.stroke();
      
      // 舒张压警戒线（90）
      const diastolicWarningY = this.getValueY(90, padding.top, height);
      ctx.beginPath();
      ctx.setStrokeStyle('#ff9900');
      ctx.moveTo(padding.left, diastolicWarningY);
      ctx.lineTo(padding.left + width, diastolicWarningY);
      ctx.stroke();
      
      // 重置线条样式
      ctx.setDash([]);
    },

    // 绘制数据曲线
    drawDataLines(ctx, data, width, height, padding) {
      const pointCount = data.length;
      if (pointCount < 2) return;
      
      const xStep = width / (pointCount - 1);
      
      // 绘制收缩压曲线
      ctx.beginPath();
      ctx.setStrokeStyle('#11B660');
      ctx.setLineWidth(2);
      
      data.forEach((item, index) => {
        const x = padding.left + (xStep * index);
        const y = this.getValueY(item.systolic, padding.top, height);
        
        if (index === 0) {
          ctx.moveTo(x, y);
        } else {
          ctx.lineTo(x, y);
        }
      });
      
      ctx.stroke();
      
      // 绘制舒张压曲线
      ctx.beginPath();
      ctx.setStrokeStyle('#4CAF50');
      ctx.setLineWidth(2);
      
      data.forEach((item, index) => {
        const x = padding.left + (xStep * index);
        const y = this.getValueY(item.diastolic, padding.top, height);
        
        if (index === 0) {
          ctx.moveTo(x, y);
        } else {
          ctx.lineTo(x, y);
        }
      });
      
      ctx.stroke();
    },

    // 绘制数据点
    drawDataPoints(ctx, data, width, height, padding) {
      const pointCount = data.length;
      const xStep = width / (pointCount - 1);
      
      // 保存数据点位置信息，用于交互
      this.data.pointsPosition = [];
      
      data.forEach((item, index) => {
        const x = padding.left + (xStep * index);
        
        // 收缩压数据点
        const systolicY = this.getValueY(item.systolic, padding.top, height);
        ctx.beginPath();
        ctx.setFillStyle('#11B660');
        ctx.arc(x, systolicY, 4, 0, 2 * Math.PI);
        ctx.fill();
        
        // 舒张压数据点
        const diastolicY = this.getValueY(item.diastolic, padding.top, height);
        ctx.beginPath();
        ctx.setFillStyle('#4CAF50');
        ctx.arc(x, diastolicY, 4, 0, 2 * Math.PI);
        ctx.fill();
        
        // 保存点位置信息
        this.data.pointsPosition.push({
          x,
          y: (systolicY + diastolicY) / 2, // 使用平均Y作为交互点
          data: item,
          radius: 20 // 交互检测半径
        });
      });
    },

    // 绘制坐标轴标签
    drawAxisLabels(ctx, data, width, height, padding) {
      const pointCount = data.length;
      const xStep = width / (pointCount - 1);
      
      ctx.setFontSize(12);
      ctx.setFillStyle('#999999');
      ctx.setTextAlign('center');
      
      // 绘制横轴日期标签
      data.forEach((item, index) => {
        const x = padding.left + (xStep * index);
        ctx.fillText(item.date, x, padding.top + height + 20);
      });
    },

    // 触摸开始事件
    touchStart(e) {
      this.handleTouch(e);
    },

    // 触摸移动事件
    touchMove(e) {
      this.handleTouch(e);
    },

    // 触摸结束事件
    touchEnd() {
      setTimeout(() => {
        this.setData({ showTooltip: false });
      }, 1500);
    },

    // 处理触摸事件，显示tooltip
    handleTouch(e) {
      const { pointsPosition } = this.data;
      if (!pointsPosition || pointsPosition.length === 0) return;
      
      const touchX = e.touches[0].x;
      const touchY = e.touches[0].y;
      
      // 查找距离触摸点最近的数据点
      let closestPoint = null;
      let minDistance = Infinity;
      
      pointsPosition.forEach(point => {
        const distance = Math.sqrt(
          Math.pow(touchX - point.x, 2) + Math.pow(touchY - point.y, 2)
        );
        
        if (distance < minDistance && distance < point.radius) {
          minDistance = distance;
          closestPoint = point;
        }
      });
      
      // 显示tooltip
      if (closestPoint) {
        this.setData({
          showTooltip: true,
          tooltipData: closestPoint.data,
          tooltipPosition: { x: touchX, y: touchY }
        });
      }
    },

    // 切换时间范围
    changeTimeRange(e) {
      const range = e.currentTarget.dataset.range;
      
      this.setData({
        timeRange: range,
        showTooltip: false
      }, () => {
        this.processChartData();
      });
    },

    // 窗口尺寸变化时重绘图表
    handleWindowResize() {
      this.initChart();
    },

    // 将血压值转换为canvas Y坐标
    getValueY(value, topPadding, height) {
      // 血压范围60-180映射到图表高度
      return topPadding + height - ((value - 60) / 120) * height;
    },

    // 格式化日期
    formatDate(date, format) {
      const year = date.getFullYear();
      const month = date.getMonth() + 1;
      const day = date.getDate();
      
      if (format === 'MM-DD') {
        return `${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
      } else if (format === 'MM月') {
        return `${month}月`;
      }
      
      return `${year}-${month}-${day}`;
    },

    // 计算平均值
    average(arr) {
      return arr.reduce((sum, val) => sum + val, 0) / arr.length;
    }
  }
})